package com.nan.hrm.service.impl;

import com.nan.hrm.AggrResoult;
import com.nan.hrm.doc.CourseDoc;
import com.nan.hrm.dto.CourseSearchDto;
import com.nan.hrm.repository.CourseRespository;
import com.nan.hrm.repository.HighlightResultMapper;
import com.nan.hrm.service.CourseEsService;
import com.nan.hrm.util.AjaxResult;
import com.nan.hrm.util.PageList;
import com.nan.hrm.vo.AggrVO;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CourseEsServiceImpl implements CourseEsService {
    @Autowired
    private CourseRespository courseRespository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    private HighlightResultMapper highlightResultMapper;
    // 添加到es中
    @Override
    public AjaxResult save(CourseDoc courseDoc) {
        // 调用持久层方法
        courseRespository.save(courseDoc);
        return AjaxResult.me();
    }
    //es中删除
    @Override
    public AjaxResult delete(Long id) {
        // 调用持久层方法
        courseRespository.deleteById(id);
        return AjaxResult.me();
    }

    @Override
    public AjaxResult searchCourse(CourseSearchDto courseSearchDto) {
        // 创建对象
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        // 指定查询的索引库和类型
        builder.withIndices("hrm");
        builder.withTypes("course");
        //排序
        String sortField = courseSearchDto.getSortField();
        if (StringUtils.isNotBlank(sortField)){
            //排序的字段=========================
            String sortFiledName = "price";
            switch (sortField.toLowerCase()){
                case "xl": sortFiledName = "saleCount";break;
                case "xp": sortFiledName = "onlineTime";break;
                case "pl": sortFiledName = "commentCount";break;
            }

            //排序方式 desc  -> SortOrder.DESC ，asc  -> SortOrder.ASC
            String sortType = courseSearchDto.getSortType();

            SortOrder sortOrder = SortOrder.ASC;

            sortOrder = StringUtils.isNotBlank(sortType)
                    && sortType.toLowerCase().equals("desc") ? SortOrder.DESC : SortOrder.ASC;

            builder.withSort(new FieldSortBuilder(sortFiledName).order(sortOrder));
        }
        //分页
        builder.withPageable(PageRequest.of(courseSearchDto.getPage()-1,courseSearchDto.getRows()));

        //boolean组合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(StringUtils.isNotBlank(courseSearchDto.getKeyword())){
            //DSL查询 ： keyword -> must -> matchQuery
            boolQueryBuilder.must(QueryBuilders.matchQuery("name",courseSearchDto.getKeyword()));
        }
        if(null != courseSearchDto.getCourseTypeId()){
            //DSL过滤 : productType -> term
            boolQueryBuilder.filter(QueryBuilders.termQuery("courseTypeId",courseSearchDto.getCourseTypeId()));
        }
        if(null != courseSearchDto.getPriceMin()){
            //DSL过滤 : priceMax;priceMin -> range
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(courseSearchDto.getPriceMin()));
        }
        if(null != courseSearchDto.getPriceMax()){
            //DSL过滤 : priceMax;priceMin -> range
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(courseSearchDto.getPriceMax()));
        }
        builder.withQuery(boolQueryBuilder);

        // 封装高亮字段
        HighlightBuilder.Field field = new HighlightBuilder.Field("name");
        field.preTags("<front style='color:red'>");
        field.postTags("</front>");
        // 高亮字段
        builder.withHighlightFields(field);


        // 聚合查询
        builder.addAggregation(AggregationBuilders.terms("grandNameAggr").field("gradeName"));
        builder.addAggregation(AggregationBuilders.terms("tenantNameAggr").field("tenantName"));



        //==================================================================
        //2.调用elasticsearchTemplate进行查询
        AggregatedPage<CourseDoc> page = elasticsearchTemplate
                .queryForPage(builder.build(), CourseDoc.class, highlightResultMapper);

        // 封装返回结果集
        Aggregations aggregations = page.getAggregations();

        Map<String , List<AggrVO>> map = new HashMap<>();
        aggregations.forEach(aggregation -> {
            List<AggrVO> aggrVOList = new ArrayList<>();
            StringTerms terms = (StringTerms) aggregation;
            terms.getBuckets().forEach(bucket -> {
                AggrVO aggrVO = new AggrVO();
                aggrVO.setKey((String)bucket.getKey());
                aggrVO.setDoc_count(bucket.getDocCount());
                aggrVOList.add(aggrVO);
            });
            map.put(aggregation.getName(),aggrVOList);
        });

//
//        PageList<CourseDoc> list = new PageList<>(page.getTotalElements(), page.getContent());
        AggrResoult aggrResoult = new AggrResoult(page.getTotalElements(), page.getContent(), map);
        //3.把结果封装成 PageList<CourseDoc> ，设置给 AjaxResult 返回
        return AjaxResult.me().setResultObj(aggrResoult);

    }


}
